Outline

  1. Make a data folder

  2. Drag favorability.csv into the data folder

  3. Make existing folder and RStudio project

  4. Open an R Markdown Notebook

  5. library(tidyverses) plus other libraries

  6. IMPORT data See Also RStudio data import wizard

  7. ATTACHE data

  8. EDA: Visualize ggplot(data = starwars, aes(hair_color)) + geom_bar()

  9. EDA: skimr::skim(starwars)

  10. EDA: summary(fav_rating)

  11. left_join(starwars, fivethirtyeight)

  12. Transform data: five dplyr verbs …

    • count / group_by & summarize
  13. Interactive visualization ggplotly

  14. Quick Linear Regression

  15. Reports: notebooks, slides, dashboards, word document, PDF, book, etc.


5. library(tidyverses) plus other libraries

library(tidyverse)
library(skimr)
library(plotly)
library(moderndive)
# library(broom)

6. read_csv(favorability.csv) See Also data import wizard

## fav_data <- read_csv("data/fav.csv")
favorability <- read_csv("https://raw.githubusercontent.com/libjohn/intro2r-code/master/data/538_favorability_popularity.csv", skip = 11)
Parsed with column specification:
cols(
  name = col_character(),
  fav_rating = col_double()
)

7 attached on-board data

dplyr::starwars

data("starwars")

8 Quick visualization

Visualize with the ggplot2 library.

plot <- ggplot(data = starwars, aes(hair_color)) + 
  geom_bar()
plot

One improvement

Arrange bars by frequency using forcats::fct_infreq

plot1 <- ggplot(data = starwars, aes(fct_infreq(hair_color))) + 
  geom_bar()
plot1

9. skimr::skim(starwars)

The skimr library presents summary EDA results using the skim() function

skim(starwars)
-- Data Summary ------------------------
                           Values  
Name                       starwars
Number of rows             87      
Number of columns          14      
_______________________            
Column type frequency:             
  character                8       
  list                     3       
  numeric                  3       
________________________           
Group variables            None    

-- Variable type: character --------------------------------------------------------------------------------
# A tibble: 8 x 8
  skim_variable n_missing complete_rate   min   max empty n_unique whitespace
* <chr>             <int>         <dbl> <int> <int> <int>    <int>      <int>
1 name                  0         1         3    21     0       87          0
2 hair_color            5         0.943     4    13     0       12          0
3 skin_color            0         1         3    19     0       31          0
4 eye_color             0         1         3    13     0       15          0
5 sex                   4         0.954     4    14     0        4          0
6 gender                4         0.954     8     9     0        2          0
7 homeworld            10         0.885     4    14     0       48          0
8 species               4         0.954     3    14     0       37          0

-- Variable type: list -------------------------------------------------------------------------------------
# A tibble: 3 x 6
  skim_variable n_missing complete_rate n_unique min_length max_length
* <chr>             <int>         <dbl>    <int>      <int>      <int>
1 films                 0             1       24          1          7
2 vehicles              0             1       11          0          2
3 starships             0             1       17          0          5

-- Variable type: numeric ----------------------------------------------------------------------------------
# A tibble: 3 x 11
  skim_variable n_missing complete_rate  mean    sd    p0   p25   p50   p75  p100 hist 
* <chr>             <int>         <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <chr>
1 height                6         0.931 174.   34.8    66 167     180 191     264 ▁▁▇▅▁
2 mass                 28         0.678  97.3 169.     15  55.6    79  84.5  1358 ▇▁▁▁▁
3 birth_year           44         0.494  87.6 155.      8  35      52  72     896 ▇▁▁▁▁

10. summary

summary(favorability)
     name             fav_rating   
 Length:14          Min.   :110.0  
 Class :character   1st Qu.:148.5  
 Mode  :character   Median :392.0  
                    Mean   :369.0  
                    3rd Qu.:559.5  
                    Max.   :610.0  

11. left_join(starwars, fivethirtyeight)

Joins or merges are part of thedplyr library.

starwars %>% 
  left_join(favorability, by = "name") %>% 
  select(name, fav_rating, everything()) %>% 
  arrange(-fav_rating)

12. Transform data:

From the dplyr library, use the five verbs …

select to subset data by columns

starwars %>% 
  select(name, gender, hair_color)

filter to subset data rows

starwars %>% 
  filter(gender == "feminine")

arrange to sort data

starwars %>% 
  arrange(desc(height), desc(name))

mutate to add new variable or transform existing

starwars %>%
  drop_na(mass) %>% 
  select(name, mass) %>% 
  mutate(big_mass = mass * 2)

count / group_by & summarize

subtotals of variables

starwars %>% 
  count(gender)

Variable totals (and also, but not here, calculations)

starwars %>% 
  drop_na(mass) %>% 
  summarise(sum(mass))

Variable subtotals and calculations

group_by(gender, species) %>% summarise(mean_height = mean(height), total = n())

starwars %>% 
  drop_na(height) %>% 
  group_by(gender, species) %>% 
  summarise(mean_height = mean(height), total = n()) %>% 
  arrange(desc(total)) %>%
  drop_na(species) %>%
  filter(total > 1) %>% 
  select(species, gender, total, everything())

13. Interactive visualization

from the plotly library

ggplotly(plot1)

14. Regression / models

Predict mass from height after eliminating Jabba from the data set. Here we’ll use primarily base R, moderndive for model outputs, and tidyverse for the pipe %>% and dplyr for data transformations. Plus, alternatively, the broom library to manipulate models.

model <- lm(mass ~ height, data = starwars %>% filter(mass < 500))
model

Call:
lm(formula = mass ~ height, data = starwars %>% filter(mass < 
    500))

Coefficients:
(Intercept)       height  
   -32.5408       0.6214  
summary(model)

Call:
lm(formula = mass ~ height, data = starwars %>% filter(mass < 
    500))

Residuals:
    Min      1Q  Median      3Q     Max 
-39.382  -8.212   0.211   3.846  57.327 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept) -32.54076   12.56053  -2.591   0.0122 *  
height        0.62136    0.07073   8.785 4.02e-12 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 19.14 on 56 degrees of freedom
Multiple R-squared:  0.5795,    Adjusted R-squared:  0.572 
F-statistic: 77.18 on 1 and 56 DF,  p-value: 4.018e-12

A nice Explanation of Basic Regression can be found in chapter 5 of the book Statistical Inference via Data Science. You can also use the moderndive library packages to access helpful functions such as: get_correlatin(), get_regression_table(), etc.

You may also appreciate or prefer the broom package for the very nice tidy(), glance(), and augment() functions.

starwars %>% 
  filter(mass < 500) %>% 
  get_correlation(mass ~ height)
# tidy(model)
get_regression_table(model)
# broom::glance(model)
get_regression_summaries(model)
# broom::augment(model)
get_regression_points(model)

Visualize regression

mass over height with a fitted linear regression line and confidence interval using geom_smooth()

starwars %>% 
  filter(mass < 500) %>%
  ggplot(aes(height, mass)) +
  geom_jitter() +
  geom_smooth(method = "lm")

15. Render reports

By changing the argument in the YAML header, you can render many report styles. A few popular examples include

type YAML syntax More information
notebook (alpha or dev) output: html_notebook Notebook
notebook (final or prod) output: html_document HTML document
Word document output: word_document MS Word
slide deck See Get Started Xaringan
dashboards   flexdashboard
e-book / web-book   Bookdown
website   Blogdown
website (simpler) Create a website / Distill
PDF output: pdf_document PDF document
LS0tDQp0aXRsZTogIlF1aWNrc3RhcnQgZGVtbyINCmF1dGhvcjogIkpvaG4gTGl0dGxlIg0KZGF0ZTogImByIFN5cy5EYXRlKClgIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KIyMgT3V0bGluZQ0KDQoxLiBNYWtlIGEgZGF0YSBmb2xkZXINCjEuIERyYWcgZmF2b3JhYmlsaXR5LmNzdiBpbnRvIHRoZSBkYXRhIGZvbGRlcg0KMS4gTWFrZSBleGlzdGluZyBmb2xkZXIgYW5kIFJTdHVkaW8gcHJvamVjdA0KMS4gT3BlbiBhbiBSIE1hcmtkb3duIE5vdGVib29rDQoxLiBgbGlicmFyeSh0aWR5dmVyc2VzKWAgIHBsdXMgb3RoZXIgbGlicmFyaWVzDQoxLiBJTVBPUlQgZGF0YSBTZWUgQWxzbyBfUlN0dWRpbyBkYXRhIGltcG9ydCB3aXphcmRfDQoxLiBBVFRBQ0hFIGRhdGENCjEuIEVEQTogVmlzdWFsaXplIGBnZ3Bsb3QoZGF0YSA9IHN0YXJ3YXJzLCBhZXMoaGFpcl9jb2xvcikpICsgZ2VvbV9iYXIoKWAgDQoxLiBFREE6IGBza2ltcjo6c2tpbShzdGFyd2FycylgDQoxLiBFREE6IHN1bW1hcnkoZmF2X3JhdGluZykNCjEuIGBsZWZ0X2pvaW4oc3RhcndhcnMsIGZpdmV0aGlydHllaWdodClgDQoxLiBUcmFuc2Zvcm0gZGF0YTogZml2ZSBkcGx5ciB2ZXJicyAuLi4NCg0KICAgIC0gYGNvdW50YCAvIGBncm91cF9ieWAgJiBgc3VtbWFyaXplYA0KICAgICAgICANCjEuIEludGVyYWN0aXZlIHZpc3VhbGl6YXRpb24gZ2dwbG90bHkNCjEuIFF1aWNrIExpbmVhciBSZWdyZXNzaW9uDQoxLiBSZXBvcnRzOiAgbm90ZWJvb2tzLCBzbGlkZXMsIGRhc2hib2FyZHMsIHdvcmQgZG9jdW1lbnQsIFBERiwgYm9vaywgZXRjLg0KDQotLS0NCg0KIyMgNS4gYGxpYnJhcnkodGlkeXZlcnNlcylgICBwbHVzIG90aGVyIGxpYnJhcmllcw0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KHNraW1yKQ0KbGlicmFyeShwbG90bHkpDQpsaWJyYXJ5KG1vZGVybmRpdmUpDQpsaWJyYXJ5KGJyb29tKQ0KYGBgDQoNCiMjIDYuIGByZWFkX2NzdihmYXZvcmFiaWxpdHkuY3N2KWAgICBTZWUgQWxzbyBkYXRhIGltcG9ydCB3aXphcmQNCg0KYGBge3J9DQojIyBmYXZfZGF0YSA8LSByZWFkX2NzdigiZGF0YS9mYXYuY3N2IikNCmZhdm9yYWJpbGl0eSA8LSByZWFkX2NzdigiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2xpYmpvaG4vaW50cm8yci1jb2RlL21hc3Rlci9kYXRhLzUzOF9mYXZvcmFiaWxpdHlfcG9wdWxhcml0eS5jc3YiLCBza2lwID0gMTEpDQpgYGANCg0KDQojIyA3IGF0dGFjaGVkIG9uLWJvYXJkIGRhdGENCg0KLSBkcGx5cjo6c3RhcndhcnMNCg0KYGRwbHlyOjpzdGFyd2Fyc2ANCg0KYGBge3J9DQpkYXRhKCJzdGFyd2FycyIpDQpgYGANCg0KIyMgOCBRdWljayB2aXN1YWxpemF0aW9uDQoNClZpc3VhbGl6ZSB3aXRoIHRoZSBgZ2dwbG90MmAgbGlicmFyeS4NCg0KYGBge3J9DQpwbG90IDwtIGdncGxvdChkYXRhID0gc3RhcndhcnMsIGFlcyhoYWlyX2NvbG9yKSkgKyANCiAgZ2VvbV9iYXIoKQ0KcGxvdA0KYGBgDQoNCiMjIyBPbmUgaW1wcm92ZW1lbnQNCg0KQXJyYW5nZSBiYXJzIGJ5IGZyZXF1ZW5jeSB1c2luZyBmb3JjYXRzOjpmY3RfaW5mcmVxDQoNCg0KYGBge3J9DQpwbG90MSA8LSBnZ3Bsb3QoZGF0YSA9IHN0YXJ3YXJzLCBhZXMoZmN0X2luZnJlcShoYWlyX2NvbG9yKSkpICsgDQogIGdlb21fYmFyKCkNCnBsb3QxDQpgYGANCg0KDQojIyA5LiBgc2tpbXI6OnNraW0oc3RhcndhcnMpYA0KDQpUaGUgYHNraW1yYCBsaWJyYXJ5IHByZXNlbnRzIHN1bW1hcnkgRURBIHJlc3VsdHMgdXNpbmcgdGhlIGBza2ltKClgIGZ1bmN0aW9uIA0KDQpgYGB7cn0NCnNraW0oc3RhcndhcnMpDQpgYGANCg0KIyMgMTAuIHN1bW1hcnkNCg0KYGBge3J9DQpzdW1tYXJ5KGZhdm9yYWJpbGl0eSkNCmBgYA0KDQojIyAxMS4gYGxlZnRfam9pbihzdGFyd2FycywgZml2ZXRoaXJ0eWVpZ2h0KWANCg0KSm9pbnMgb3IgbWVyZ2VzIGFyZSBwYXJ0IG9mIHRoZWBkcGx5cmAgbGlicmFyeS4NCg0KYGBge3J9DQpzdGFyd2FycyAlPiUgDQogIGxlZnRfam9pbihmYXZvcmFiaWxpdHksIGJ5ID0gIm5hbWUiKSAlPiUgDQogIHNlbGVjdChuYW1lLCBmYXZfcmF0aW5nLCBldmVyeXRoaW5nKCkpICU+JSANCiAgYXJyYW5nZSgtZmF2X3JhdGluZykNCmBgYA0KDQoNCiMjIDEyLiBUcmFuc2Zvcm0gZGF0YTogDQoNCkZyb20gdGhlIGBkcGx5cmAgbGlicmFyeSwgdXNlIHRoZSBmaXZlICB2ZXJicyAuLi4NCg0KIyMjIGBzZWxlY3RgIHRvIHN1YnNldCBkYXRhIGJ5IGNvbHVtbnMNCg0KYGBge3J9DQpzdGFyd2FycyAlPiUgDQogIHNlbGVjdChuYW1lLCBnZW5kZXIsIGhhaXJfY29sb3IpDQpgYGANCg0KIyMjIGBmaWx0ZXJgIHRvIHN1YnNldCBkYXRhIHJvd3MgDQoNCmBgYHtyfQ0Kc3RhcndhcnMgJT4lIA0KICBmaWx0ZXIoZ2VuZGVyID09ICJmZW1pbmluZSIpDQpgYGANCg0KIyMjIGBhcnJhbmdlYCB0byBzb3J0IGRhdGENCg0KYGBge3J9DQpzdGFyd2FycyAlPiUgDQogIGFycmFuZ2UoZGVzYyhoZWlnaHQpLCBkZXNjKG5hbWUpKQ0KYGBgDQoNCiMjIyBgbXV0YXRlYCB0byBhZGQgbmV3IHZhcmlhYmxlIG9yIHRyYW5zZm9ybSBleGlzdGluZw0KDQpgYGB7cn0NCnN0YXJ3YXJzICU+JQ0KICBkcm9wX25hKG1hc3MpICU+JSANCiAgc2VsZWN0KG5hbWUsIG1hc3MpICU+JSANCiAgbXV0YXRlKGJpZ19tYXNzID0gbWFzcyAqIDIpDQpgYGANCg0KDQojIyMgYGNvdW50YCAvIGBncm91cF9ieWAgJiBgc3VtbWFyaXplYA0KDQpzdWJ0b3RhbHMgb2YgdmFyaWFibGVzDQoNCg0KYGBge3J9DQpzdGFyd2FycyAlPiUgDQogIGNvdW50KGdlbmRlcikNCmBgYA0KDQpWYXJpYWJsZSB0b3RhbHMgKGFuZCBhbHNvLCBidXQgbm90IGhlcmUsIGNhbGN1bGF0aW9ucykNCg0KYGBge3J9DQpzdGFyd2FycyAlPiUgDQogIGRyb3BfbmEobWFzcykgJT4lIA0KICBzdW1tYXJpc2Uoc3VtKG1hc3MpKQ0KYGBgDQoNClZhcmlhYmxlIHN1YnRvdGFscyBhbmQgY2FsY3VsYXRpb25zDQoNCj4gYGdyb3VwX2J5KGdlbmRlciwgc3BlY2llcykgJT4lIA0KICAgc3VtbWFyaXNlKG1lYW5faGVpZ2h0ID0gbWVhbihoZWlnaHQpLCB0b3RhbCA9IG4oKSlgDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpzdGFyd2FycyAlPiUgDQogIGRyb3BfbmEoaGVpZ2h0KSAlPiUgDQogIGdyb3VwX2J5KGdlbmRlciwgc3BlY2llcykgJT4lIA0KICBzdW1tYXJpc2UobWVhbl9oZWlnaHQgPSBtZWFuKGhlaWdodCksIHRvdGFsID0gbigpKSAlPiUgDQogIGFycmFuZ2UoZGVzYyh0b3RhbCkpICU+JQ0KICBkcm9wX25hKHNwZWNpZXMpICU+JQ0KICBmaWx0ZXIodG90YWwgPiAxKSAlPiUgDQogIHNlbGVjdChzcGVjaWVzLCBnZW5kZXIsIHRvdGFsLCBldmVyeXRoaW5nKCkpDQpgYGANCg0KIyMgMTMuIEludGVyYWN0aXZlIHZpc3VhbGl6YXRpb24NCg0KZnJvbSB0aGUgYHBsb3RseWAgbGlicmFyeQ0KDQoNCmBgYHtyfQ0KZ2dwbG90bHkocGxvdDEpDQpgYGANCg0KIyMgMTQuIFJlZ3Jlc3Npb24gLyBtb2RlbHMNCg0KUHJlZGljdCBtYXNzIGZyb20gaGVpZ2h0IGFmdGVyIGVsaW1pbmF0aW5nIEphYmJhIGZyb20gdGhlIGRhdGEgc2V0LiAgSGVyZSB3ZSdsbCB1c2UgcHJpbWFyaWx5IGJhc2UgUiwgYG1vZGVybmRpdmVgIGZvciBtb2RlbCBvdXRwdXRzLCBhbmQgdGlkeXZlcnNlIGZvciB0aGUgcGlwZSBgJT4lYCBhbmQgYGRwbHlyYCBmb3IgZGF0YSB0cmFuc2Zvcm1hdGlvbnMuICBQbHVzLCBhbHRlcm5hdGl2ZWx5LCB0aGUgYGJyb29tYCBsaWJyYXJ5IHRvIG1hbmlwdWxhdGUgbW9kZWxzLiANCg0KYGBge3J9DQptb2RlbCA8LSBsbShtYXNzIH4gaGVpZ2h0LCBkYXRhID0gc3RhcndhcnMgJT4lIGZpbHRlcihtYXNzIDwgNTAwKSkNCm1vZGVsDQpzdW1tYXJ5KG1vZGVsKQ0KYGBgDQoNCkEgbmljZSBfRXhwbGFuYXRpb24gb2YgQmFzaWMgUmVncmVzc2lvbl8gY2FuIGJlIGZvdW5kIGluIFtjaGFwdGVyIDVdKGh0dHBzOi8vbW9kZXJuZGl2ZS5jb20vNS1yZWdyZXNzaW9uLmh0bWwpIG9mIHRoZSBib29rIFtfU3RhdGlzdGljYWwgSW5mZXJlbmNlIHZpYSBEYXRhIFNjaWVuY2VfXShodHRwczovL21vZGVybmRpdmUuY29tLykuICBZb3UgY2FuIGFsc28gdXNlIHRoZSBgbW9kZXJuZGl2ZWANCmxpYnJhcnkgcGFja2FnZXMgdG8gYWNjZXNzIGhlbHBmdWwgZnVuY3Rpb25zIHN1Y2ggYXM6ICBgZ2V0X2NvcnJlbGF0aW4oKWAsIGBnZXRfcmVncmVzc2lvbl90YWJsZSgpYCwgZXRjLg0KDQpZb3UgbWF5IGFsc28gYXBwcmVjaWF0ZSBvciBwcmVmZXIgdGhlIFticm9vbV0oaHR0cHM6Ly9icm9vbS50aWR5dmVyc2Uub3JnKSBwYWNrYWdlIGZvciB0aGUgdmVyeSBuaWNlIGB0aWR5KClgLCBgZ2xhbmNlKClgLCBhbmQgYGF1Z21lbnQoKWAgZnVuY3Rpb25zLg0KDQpgYGB7cn0NCnN0YXJ3YXJzICU+JSANCiAgZmlsdGVyKG1hc3MgPCA1MDApICU+JSANCiAgZ2V0X2NvcnJlbGF0aW9uKG1hc3MgfiBoZWlnaHQpDQpgYGANCg0KDQpgYGB7cn0NCiMgdGlkeShtb2RlbCkNCmdldF9yZWdyZXNzaW9uX3RhYmxlKG1vZGVsKQ0KYGBgDQoNCmBgYHtyfQ0KIyBicm9vbTo6Z2xhbmNlKG1vZGVsKQ0KZ2V0X3JlZ3Jlc3Npb25fc3VtbWFyaWVzKG1vZGVsKQ0KYGBgDQoNCg0KYGBge3J9DQojIGJyb29tOjphdWdtZW50KG1vZGVsKQ0KZ2V0X3JlZ3Jlc3Npb25fcG9pbnRzKG1vZGVsKQ0KYGBgDQoNCiMjIyBWaXN1YWxpemUgcmVncmVzc2lvbg0KDQpgbWFzc2Agb3ZlciBgaGVpZ2h0YCB3aXRoIGEgZml0dGVkIGxpbmVhciByZWdyZXNzaW9uIGxpbmUgYW5kIGNvbmZpZGVuY2UgaW50ZXJ2YWwgdXNpbmcgYGdlb21fc21vb3RoKClgDQoNCmBgYHtyfQ0Kc3RhcndhcnMgJT4lIA0KICBmaWx0ZXIobWFzcyA8IDUwMCkgJT4lDQogIGdncGxvdChhZXMoaGVpZ2h0LCBtYXNzKSkgKw0KICBnZW9tX2ppdHRlcigpICsNCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIikNCmBgYA0KDQojIyAxNS4gUmVuZGVyIHJlcG9ydHMNCg0KQnkgY2hhbmdpbmcgdGhlIGFyZ3VtZW50IGluIHRoZSBZQU1MIGhlYWRlciwgeW91IGNhbiByZW5kZXIgbWFueSByZXBvcnQgc3R5bGVzLiAgQSBmZXcgcG9wdWxhciBleGFtcGxlcyBpbmNsdWRlDQoNCnR5cGUgfCBZQU1MIHN5bnRheCB8IE1vcmUgaW5mb3JtYXRpb24NCi0tLSB8IC0tLSB8IC0tLQ0Kbm90ZWJvb2sgKGFscGhhIG9yIGRldikgfCBvdXRwdXQ6IGh0bWxfbm90ZWJvb2sgfCBbTm90ZWJvb2tdKGh0dHBzOi8vYm9va2Rvd24ub3JnL3lpaHVpL3JtYXJrZG93bi9ub3RlYm9vay5odG1sKQ0Kbm90ZWJvb2sgKGZpbmFsIG9yIHByb2QpIHwgb3V0cHV0OiBodG1sX2RvY3VtZW50IHwgW0hUTUwgZG9jdW1lbnRdKGh0dHBzOi8vYm9va2Rvd24ub3JnL3lpaHVpL3JtYXJrZG93bi9odG1sLWRvY3VtZW50Lmh0bWwpDQpXb3JkIGRvY3VtZW50IHwgb3V0cHV0OiB3b3JkX2RvY3VtZW50IHwgW01TIFdvcmRdKGh0dHBzOi8vYm9va2Rvd24ub3JnL3lpaHVpL3JtYXJrZG93bi93b3JkLWRvY3VtZW50Lmh0bWwpDQpzbGlkZSBkZWNrIHwgU2VlIFtHZXQgU3RhcnRlZF0oaHR0cHM6Ly9zbGlkZXMueWlodWkub3JnL3hhcmluZ2FuLyM0KSB8IFtYYXJpbmdhbl0oaHR0cHM6Ly9zbGlkZXMueWlodWkub3JnL3hhcmluZ2FuLyMxKQ0KZGFzaGJvYXJkcyB8ICZuYnNwOyB8IFtmbGV4ZGFzaGJvYXJkXShodHRwczovL3JtYXJrZG93bi5yc3R1ZGlvLmNvbS9mbGV4ZGFzaGJvYXJkLykgfCBbc2hpbnldKGh0dHBzOi8vc2hpbnkucnN0dWRpby5jb20vKQ0KZS1ib29rIC8gd2ViLWJvb2sgfCAmbmJzcDsgfCBbQm9va2Rvd25dKGh0dHBzOi8vYm9va2Rvd24ub3JnL3lpaHVpL2Jvb2tkb3duLykNCndlYnNpdGUgfCAmbmJzcDsgfCBbQmxvZ2Rvd25dKGh0dHBzOi8vYm9va2Rvd24ub3JnL3lpaHVpL2Jsb2dkb3duLykNCndlYnNpdGUgKHNpbXBsZXIpIHwgfCBbQ3JlYXRlIGEgd2Vic2l0ZSAvIERpc3RpbGxdKGh0dHBzOi8vcnN0dWRpby5naXRodWIuaW8vZGlzdGlsbC93ZWJzaXRlLmh0bWwpDQpQREYgfCBvdXRwdXQ6IHBkZl9kb2N1bWVudCB8IFtQREYgZG9jdW1lbnRdKGh0dHBzOi8vYm9va2Rvd24ub3JnL3lpaHVpL3JtYXJrZG93bi9wZGYtZG9jdW1lbnQuaHRtbCkNCg0KDQoNCg==